using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace MT5Trade.Tests.TestFramework
{
    /// <summary>
    /// 测试数据访问接口
    /// 遵循 generic-rule.md 规则：所有测试数据必须来自MySQL表
    /// </summary>
    public interface ITestDataDao
    {
        // MarketData方法
        Task<List<MarketDataTestEntity>> QueryMarketDataAsync(MarketDataTestFilter filter);
        Task<int> InsertMarketDataAsync(MarketDataTestEntity entity);
        Task<int> InsertPerformanceTestAsync(CachePerformanceTestEntity entity);
        Task<Dictionary<string, string>> GetTestConfigurationAsync();
        Task ExecuteSqlAsync(string sql);

        // 套利测试场景
        Task<List<ArbitrageTestScenario>> GetArbitrageTestScenariosAsync();
        Task<List<ArbitrageTestScenario>> GetBoundaryTestScenariosAsync();
        Task<List<ArbitrageTestScenario>> GetFailureTestScenariosAsync();

        // GARCH测试数据
        Task<List<GarchTestData>> GetGarchTestDataAsync();

        // VaR测试数据
        Task<List<VarTestData>> GetVarTestDataAsync();

        // 市场条件测试
        Task<List<MarketConditionTestData>> GetMarketConditionTestDataAsync();

        // 历史交易记录
        Task<List<TradeHistory>> GetTradeHistoryAsync(string batchId);
        Task<List<TradeHistory>> GetRecentTradeHistoryAsync(int limit = 20);

        // KKT验证数据
        Task<List<KktVerificationData>> GetKktVerificationDataAsync();

        // 边界条件测试
        Task<List<BoundaryTestCase>> GetBoundaryTestCasesAsync();

        // 测试结果记录
        Task InsertTestResultAsync(TestExecutionResult result);
        Task<List<TestExecutionResult>> GetTestResultsAsync(string testClass, string testMethod);

        // 数据初始化
        Task<bool> InitializeTestDataAsync();
        Task<bool> CleanupTestDataAsync();

        // 新增的方法（用于重构后的测试）
        Task<List<ConsecutiveLossTestSequence>> GetConsecutiveLossTestSequencesAsync();
        Task<List<TradeSequenceItem>> GetTradeSequenceAsync(int sequenceId);
        Task<List<DynamicAdjustmentScenario>> GetDynamicAdjustmentScenariosAsync();
        Task<List<HistoricalTrade>> GetHistoricalTradesForScenarioAsync(int scenarioId);
        Task<List<BonusConsumptionScenario>> GetBonusConsumptionScenariosAsync();
        Task<List<MarginLevelScenario>> GetMarginLevelScenariosAsync();
    }

    #region 数据实体类

    /// <summary>
    /// 套利测试场景
    /// </summary>
    public class ArbitrageTestScenario
    {
        public int Id { get; set; }
        public string ScenarioName { get; set; }
        public string ScenarioType { get; set; }
        public decimal MainLossProbability { get; set; }
        public decimal ExpectedMove { get; set; }
        public decimal Spread { get; set; }
        public decimal BonusRemaining { get; set; }
        public decimal FollowerMarginLevel { get; set; }
        public decimal Volatility { get; set; }
        public decimal? ExpectedGapMin { get; set; }
        public decimal? ExpectedGapMax { get; set; }
        public bool ShouldSucceed { get; set; }
        public string FailureReason { get; set; }
        public DateTime CreatedAt { get; set; }
    }

    /// <summary>
    /// GARCH测试数据
    /// </summary>
    public class GarchTestData
    {
        public int Id { get; set; }
        public string TestCaseName { get; set; }
        public decimal CurrentReturn { get; set; }
        public decimal CurrentVolatility { get; set; }
        public decimal ExpectedVolMin { get; set; }
        public decimal ExpectedVolMax { get; set; }
        public decimal GarchOmega { get; set; }
        public decimal GarchAlpha { get; set; }
        public decimal GarchBeta { get; set; }
        public DateTime TestDate { get; set; }
    }

    /// <summary>
    /// VaR测试数据
    /// </summary>
    public class VarTestData
    {
        public int Id { get; set; }
        public string TestCaseName { get; set; }
        public decimal EntryPrice { get; set; }
        public decimal AccountEquity { get; set; }
        public decimal PositionSize { get; set; }
        public decimal Volatility { get; set; }
        public decimal ExpectedReturn { get; set; }
        public decimal ConfidenceLevel { get; set; }
        public decimal MaxLossPercentage { get; set; }
        public decimal? ExpectedStopLossMin { get; set; }
        public decimal? ExpectedStopLossMax { get; set; }
    }

    /// <summary>
    /// 市场条件测试数据
    /// </summary>
    public class MarketConditionTestData
    {
        public int Id { get; set; }
        public string ConditionName { get; set; }
        public bool IsAtStrongResistance { get; set; }
        public bool IsAtStrongSupport { get; set; }
        public bool IsBullish { get; set; }
        public decimal RSI { get; set; }
        public decimal TrendExhaustion { get; set; }
        public decimal ExpectedMove { get; set; }
        public decimal Spread { get; set; }
        public decimal BonusRemaining { get; set; }
        public decimal FollowerMarginLevel { get; set; }
        public decimal Volatility { get; set; }
        public decimal ExpectedQualityMin { get; set; }
        public decimal ExpectedQualityMax { get; set; }
        public decimal ExpectedMainLossMin { get; set; }
        public decimal ExpectedMainLossMax { get; set; }
    }

    /// <summary>
    /// 历史交易记录
    /// </summary>
    public class TradeHistory
    {
        public int Id { get; set; }
        public string BatchId { get; set; }
        public int SequenceNumber { get; set; }
        public DateTime TradeTime { get; set; }
        public bool IsProfitable { get; set; }
        public decimal GapUsed { get; set; }
        public decimal BaseGap { get; set; }
        public decimal AdjustmentFactor { get; set; }
        public decimal? WinRate { get; set; }
        public int ConsecutiveLosses { get; set; }
    }

    /// <summary>
    /// KKT条件验证数据
    /// </summary>
    public class KktVerificationData
    {
        public int Id { get; set; }
        public string TestCaseName { get; set; }
        public decimal GapValue { get; set; }
        public decimal Gradient { get; set; }
        public decimal? Lambda1 { get; set; }
        public decimal? Lambda2 { get; set; }
        public bool? StationaritySatisfied { get; set; }
        public bool? PrimalFeasible { get; set; }
        public bool? DualFeasible { get; set; }
        public bool? ComplementarySlack { get; set; }
        public bool? KktSatisfied { get; set; }
        public decimal Tolerance { get; set; }
    }

    /// <summary>
    /// 边界条件测试用例
    /// </summary>
    public class BoundaryTestCase
    {
        public int Id { get; set; }
        public string TestName { get; set; }
        public string TestType { get; set; }
        public string ParamName { get; set; }
        public decimal? ParamValue { get; set; }
        public bool ShouldThrowException { get; set; }
        public string ExpectedExceptionType { get; set; }
        public string ExpectedBehavior { get; set; }
    }

    /// <summary>
    /// 测试执行结果
    /// </summary>
    public class TestExecutionResult
    {
        public int Id { get; set; }
        public string TestClass { get; set; }
        public string TestMethod { get; set; }
        public int? TestCaseId { get; set; }
        public string InputParams { get; set; } // JSON
        public decimal? ActualResult { get; set; }
        public decimal? ExpectedResult { get; set; }
        public decimal? Deviation { get; set; }
        public bool Passed { get; set; }
        public string ErrorMessage { get; set; }
        public int? ExecutionTimeMs { get; set; }
        public DateTime ExecutedAt { get; set; }
    }

    #endregion

    #region MarketData相关实体类

    /// <summary>
    /// 市场数据测试实体
    /// </summary>
    public class MarketDataTestEntity
    {
        public long Id { get; set; }
        public string Symbol { get; set; }
        public DateTime Time { get; set; }
        public decimal Open { get; set; }
        public decimal High { get; set; }
        public decimal Low { get; set; }
        public decimal Close { get; set; }
        public long Volume { get; set; }
        public string IntervalType { get; set; }
        public string DataSource { get; set; }
        public DateTime CreatedAt { get; set; }

        /// <summary>
        /// 转换为MarketTick
        /// </summary>
        public MT5Trade.Models.MarketData.MarketTick ToMarketTick()
        {
            return new MT5Trade.Models.MarketData.MarketTick
            {
                Symbol = Symbol,
                Time = Time,
                Open = Open,
                High = High,
                Low = Low,
                Close = Close,
                Volume = Volume
            };
        }
    }

    /// <summary>
    /// 市场数据查询过滤器
    /// </summary>
    public class MarketDataTestFilter
    {
        public string Symbol { get; set; }
        public DateTime? StartTime { get; set; }
        public DateTime? EndTime { get; set; }
        public string IntervalType { get; set; }
        public int Limit { get; set; } = 100;

        public string BuildQuery()
        {
            var sql = "SELECT * FROM market_data_test WHERE 1=1";

            if (!string.IsNullOrEmpty(Symbol))
                sql += $" AND symbol = '{Symbol}'";

            if (StartTime.HasValue)
                sql += $" AND time >= '{StartTime.Value:yyyy-MM-dd HH:mm:ss}'";

            if (EndTime.HasValue)
                sql += $" AND time <= '{EndTime.Value:yyyy-MM-dd HH:mm:ss}'";

            if (!string.IsNullOrEmpty(IntervalType))
                sql += $" AND interval_type = '{IntervalType}'";

            sql += " ORDER BY time ASC";

            if (Limit > 0)
                sql += $" LIMIT {Limit}";

            return sql;
        }
    }

    /// <summary>
    /// 缓存性能测试实体
    /// </summary>
    public class CachePerformanceTestEntity
    {
        public int Id { get; set; }
        public string TestName { get; set; }
        public string TestCaseId { get; set; }
        public string OperationType { get; set; }
        public int DataCount { get; set; }
        public decimal? FileSizeKb { get; set; }
        public long DurationMs { get; set; }
        public decimal? MemoryUsedMb { get; set; }
        public decimal? CpuUsagePercent { get; set; }
        public decimal? SpeedupRatio { get; set; }
        public decimal? CacheHitRate { get; set; }
        public DateTime TestTime { get; set; }
        public string TestEnvironment { get; set; }

        public static CachePerformanceTestEntity Create(
            string testName,
            string caseId,
            string operationType,
            int dataCount,
            long durationMs)
        {
            return new CachePerformanceTestEntity
            {
                TestName = testName,
                TestCaseId = caseId,
                OperationType = operationType,
                DataCount = dataCount,
                DurationMs = durationMs,
                TestTime = DateTime.Now,
                TestEnvironment = Environment.MachineName
            };
        }
    }

    #endregion

    #region 新增的测试数据实体类

    /// <summary>
    /// 连续亏损测试序列
    /// </summary>
    public class ConsecutiveLossTestSequence
    {
        public int Id { get; set; }
        public string SequenceName { get; set; }
        public decimal BaseGap { get; set; }
        public int ExpectedFinalConsecutiveLosses { get; set; }
        public string Description { get; set; }
    }

    /// <summary>
    /// 交易序列项
    /// </summary>
    public class TradeSequenceItem
    {
        public int Id { get; set; }
        public int SequenceId { get; set; }
        public int OrderIndex { get; set; }
        public bool IsWin { get; set; }
        public decimal IntervalSeconds { get; set; }
    }

    /// <summary>
    /// 动态调整场景
    /// </summary>
    public class DynamicAdjustmentScenario
    {
        public int Id { get; set; }
        public string ScenarioName { get; set; }
        public decimal BaseGap { get; set; }
        public decimal TargetWinRate { get; set; }
        public decimal ExpectedAdjustmentFactor { get; set; }
        public decimal ExpectedMinGap { get; set; }
        public decimal ExpectedMaxGap { get; set; }
    }

    /// <summary>
    /// 历史交易记录
    /// </summary>
    public class HistoricalTrade
    {
        public int Id { get; set; }
        public int ScenarioId { get; set; }
        public bool IsWin { get; set; }
        public decimal IntervalSeconds { get; set; }
        public decimal PnL { get; set; }
    }

    /// <summary>
    /// 赠金消耗场景
    /// </summary>
    public class BonusConsumptionScenario
    {
        public int Id { get; set; }
        public string ScenarioName { get; set; }
        public decimal BonusRemaining { get; set; }
        public decimal MainLossProbability { get; set; }
        public decimal ExpectedMove { get; set; }
        public decimal Spread { get; set; }
        public decimal FollowerMarginLevel { get; set; }
        public decimal CurrentVolatility { get; set; }
        public decimal ExpectedMinGap { get; set; }
        public decimal ExpectedMaxGap { get; set; }
    }

    /// <summary>
    /// 保证金水平场景
    /// </summary>
    public class MarginLevelScenario
    {
        public int Id { get; set; }
        public string ScenarioName { get; set; }
        public decimal MarginLevel { get; set; }
        public decimal MainLossProbability { get; set; }
        public decimal ExpectedMove { get; set; }
        public decimal Spread { get; set; }
        public decimal BonusRemaining { get; set; }
        public decimal CurrentVolatility { get; set; }
        public decimal ExpectedMinGap { get; set; }
        public decimal ExpectedMaxGap { get; set; }
    }

    #endregion
}